package com.hhq.sso.system.service.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import org.springblade.core.tool.constant.RoleConstant;
import org.springblade.core.tool.node.ForestNodeMerger;
import org.springblade.core.tool.utils.CollectionUtil;
import org.springblade.core.tool.utils.Func;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hhq.sso.common.util.WebContext;
import com.hhq.sso.system.entity.Role;
import com.hhq.sso.system.entity.RoleMenu;
import com.hhq.sso.system.entity.RoleScope;
import com.hhq.sso.system.mapper.RoleMapper;
import com.hhq.sso.system.service.IRoleMenuService;
import com.hhq.sso.system.service.IRoleScopeService;
import com.hhq.sso.system.service.IRoleService;

import jakarta.validation.constraints.NotEmpty;
import lombok.AllArgsConstructor;

/**
 * 服务实现类
 *
 * @author Chill
 */
@Service
@Validated
@AllArgsConstructor
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements IRoleService {

    private final IRoleMenuService roleMenuService;
    private final IRoleScopeService roleScopeService;

    @Override
    public IPage<Role> selectRolePage(IPage<Role> page, Role role) {
        return page.setRecords(baseMapper.selectRolePage(page, role));
    }

    @Override
    public List<Role> tree(String tenantId) {
        String userRole = WebContext.getRoleId();
        String excludeRole = null;
        if (!CollectionUtil.contains(Func.toStrArray(userRole), RoleConstant.ADMIN)) {
            excludeRole = RoleConstant.ADMIN;
        }
        return ForestNodeMerger.merge(baseMapper.tree(tenantId, excludeRole));
    }

    @Override
    public boolean grant(@NotEmpty List<Long> roleIds, @NotEmpty List<Long> menuIds, List<Long> dataScopeIds) {
        // 删除角色配置的菜单集合
        roleMenuService.remove(Wrappers.<RoleMenu>update().lambda().in(RoleMenu::getRoleId, roleIds));
        // 组装配置
        List<RoleMenu> roleMenus = new ArrayList<>();
        roleIds.forEach(roleId -> menuIds.forEach(menuId -> {
            RoleMenu roleMenu = new RoleMenu();
            roleMenu.setRoleId(roleId);
            roleMenu.setMenuId(menuId);
            roleMenus.add(roleMenu);
        }));
        // 新增配置
        roleMenuService.saveBatch(roleMenus);

        // 删除角色配置的数据权限集合
        roleScopeService.remove(Wrappers.<RoleScope>update().lambda().in(RoleScope::getRoleId, roleIds));
        // 组装配置
        List<RoleScope> roleDataScopes = new ArrayList<>();
        roleIds.forEach(roleId -> dataScopeIds.forEach(scopeId -> {
            RoleScope roleScope = new RoleScope();
            roleScope.setRoleId(roleId);
            roleScope.setScopeId(scopeId);
            roleDataScopes.add(roleScope);
        }));
        // 新增配置
        roleScopeService.saveBatch(roleDataScopes);

        return true;
    }

    @Override
    public String getRoleIds(String tenantId, String roleNames) {
        List<Role> roleList = baseMapper.selectList(Wrappers.<Role>query().lambda().eq(Role::getTenantId, tenantId)
            .in(Role::getRoleName, Func.toStrList(roleNames)));
        if (roleList != null && roleList.size() > 0) {
            return roleList.stream().map(role -> Func.toStr(role.getId())).distinct().collect(Collectors.joining(","));
        }
        return null;
    }

    @Override
    public List<String> getRoleNames(String roleIds) {
        return baseMapper.getRoleNames(Func.toLongArray(roleIds));
    }

}
